package main

import (
	"fmt"
	"jdfs2/internal/storage"
	"time"
)

func runCrossVolumeReplicaExample() {
	fmt.Println("=== 跨卷副本功能示例 ===")

	// 1. 创建跨卷文件元数据
	meta := storage.NewDistributedObjectMeta()
	meta.Size = 3584 // 3.5KB
	meta.ETag = "cross-volume-etag-123"
	meta.LastModified = time.Now().Unix()
	meta.ContentType = "application/octet-stream"

	// 2. 设置跨卷存储片段
	meta.Segments = []storage.VolumeSegment{
		{SegmentID: 1, VolumeID: 1, Offset: 0, Size: 1024}, // 第1个片段在卷1
		{SegmentID: 2, VolumeID: 2, Offset: 0, Size: 2048}, // 第2个片段在卷2
		{SegmentID: 3, VolumeID: 3, Offset: 0, Size: 512},  // 第3个片段在卷3
	}

	fmt.Printf("文件大小: %d 字节\n", meta.Size)
	fmt.Printf("跨卷片段数: %d\n", len(meta.Segments))
	for _, seg := range meta.Segments {
		fmt.Printf("  片段%d: 卷%d, 偏移%d, 大小%d\n", seg.SegmentID, seg.VolumeID, seg.Offset, seg.Size)
	}

	// 3. 创建跨卷副本
	fmt.Println("\n=== 创建跨卷副本 ===")
	meta.AddReplicaFromSegments("node-001", meta.Segments)
	meta.AddReplicaFromSegments("node-002", meta.Segments)

	// 4. 创建单卷副本（向后兼容）
	fmt.Println("=== 创建单卷副本 ===")
	singleReplica := storage.NewReplicaInfo("node-003", 1, 0, 3584)
	meta.AddReplica(singleReplica)

	// 5. 显示副本信息
	fmt.Printf("\n总副本数: %d\n", meta.GetReplicaCount())

	// 跨卷副本
	multiVolumeReplicas := meta.GetMultiVolumeReplicas()
	fmt.Printf("跨卷副本数: %d\n", len(multiVolumeReplicas))
	for _, replica := range multiVolumeReplicas {
		fmt.Printf("  节点: %s, 片段数: %d, 总大小: %d\n",
			replica.NodeID, replica.GetSegmentCount(), replica.GetTotalSize())
		volumeIDs := replica.GetVolumeIDs()
		fmt.Printf("    卷ID: %v\n", volumeIDs)
	}

	// 单卷副本
	singleVolumeReplicas := meta.GetSingleVolumeReplicas()
	fmt.Printf("单卷副本数: %d\n", len(singleVolumeReplicas))
	for _, replica := range singleVolumeReplicas {
		fmt.Printf("  节点: %s, 卷ID: %d, 大小: %d\n",
			replica.NodeID, replica.VolumeID, replica.Size)
	}

	// 6. 按卷查询副本
	fmt.Println("\n=== 按卷查询副本 ===")
	for volumeID := int32(1); volumeID <= 3; volumeID++ {
		replicas := meta.GetReplicasByVolume(volumeID)
		fmt.Printf("卷%d的副本数: %d\n", volumeID, len(replicas))
		for _, replica := range replicas {
			fmt.Printf("  节点: %s\n", replica.NodeID)
		}
	}

	// 7. 按节点查询副本
	fmt.Println("\n=== 按节点查询副本 ===")
	for _, nodeID := range []string{"node-001", "node-002", "node-003"} {
		replica := meta.GetReplicaByNode(nodeID)
		if replica != nil {
			fmt.Printf("节点%s: 跨卷=%v, 片段数=%d, 总大小=%d\n",
				nodeID, replica.IsMultiVolume(), replica.GetSegmentCount(), replica.GetTotalSize())
		}
	}

	// 8. 演示副本状态管理
	fmt.Println("\n=== 副本状态管理 ===")
	node1Replica := meta.GetReplicaByNode("node-001")
	if node1Replica != nil {
		fmt.Printf("节点001初始状态: %s\n", node1Replica.Status.String())

		// 更新为同步状态
		node1Replica.UpdateStatus(storage.ReplicaStatusSyncing)
		fmt.Printf("更新后状态: %s, 是否活跃: %v\n",
			node1Replica.Status.String(), node1Replica.IsActive())

		// 恢复活跃状态
		node1Replica.UpdateStatus(storage.ReplicaStatusActive)
		fmt.Printf("恢复后状态: %s, 是否活跃: %v\n",
			node1Replica.Status.String(), node1Replica.IsActive())
	}

	// 9. 演示片段操作
	fmt.Println("\n=== 片段操作 ===")
	node4Replica := &storage.ReplicaInfo{
		NodeID:    "node-004",
		Status:    storage.ReplicaStatusActive,
		UpdatedAt: time.Now().Unix(),
		Segments:  make([]storage.ReplicaSegment, 0),
	}

	// 添加片段
	node4Replica.AddSegment(1, 0, 1024)
	node4Replica.AddSegment(2, 0, 2048)
	fmt.Printf("添加片段后: 片段数=%d, 总大小=%d, 跨卷=%v\n",
		node4Replica.GetSegmentCount(), node4Replica.GetTotalSize(), node4Replica.IsMultiVolume())

	// 移除片段
	node4Replica.RemoveSegment(1)
	fmt.Printf("移除片段后: 片段数=%d, 总大小=%d, 跨卷=%v\n",
		node4Replica.GetSegmentCount(), node4Replica.GetTotalSize(), node4Replica.IsMultiVolume())

	// 10. 序列化性能测试
	fmt.Println("\n=== 序列化性能测试 ===")
	start := time.Now()
	data, err := meta.Serialize()
	if err != nil {
		fmt.Printf("序列化失败: %v\n", err)
		return
	}
	serializeTime := time.Since(start)

	start = time.Now()
	var newMeta storage.DistributedObjectMeta
	err = newMeta.Deserialize(data)
	if err != nil {
		fmt.Printf("反序列化失败: %v\n", err)
		return
	}
	deserializeTime := time.Since(start)

	fmt.Printf("序列化大小: %d 字节\n", len(data))
	fmt.Printf("序列化时间: %v\n", serializeTime)
	fmt.Printf("反序列化时间: %v\n", deserializeTime)
	fmt.Printf("反序列化后副本数: %d\n", newMeta.GetReplicaCount())

	fmt.Println("\n=== 示例完成 ===")
}

func main() {
	runCrossVolumeReplicaExample()
}
